// Map builder
//--------------------------------
#ifndef MAPBUILDER_H
#define MAPBUILDER_H
#include "common.h"
#include "generator.h"

struct Room {
    Room( int l = 0, int r = 0, int t = 0, int b = 0 )
    : left( l ), right( r ), top( t ), bottom( b ) { }
    int left;
    int right;
    int top;
    int bottom;
};

class RoomBuilder {
public:

    RoomBuilder();
    virtual ~RoomBuilder() { }

    virtual void GetRoomSize( int& width, int& height ) const = 0;
            void SetBuildTarget( Map* map, const Room& area );
            void BuildRoom();

protected:

    uint GetTile( int x, int y ) const;
    void SetTile( int x, int y, uint type );

    virtual void BuildInternal( int width, int height ) = 0;

private:

    Map* _targetMap;
    Room _targetRoom;

};

class MapBuilder {
public:

    MapBuilder() { }
    ~MapBuilder() { }

    template< class RoomBuilder >
    void AddRoomBuilder( uint weight );
    Map* BuildMap( Game& game, uint tiles, double deadEndRetryChance = 0.2 );

private:

    static const uint BORDER;

    typedef Generator< RoomBuilder > RoomBuilderGenerator;
    RoomBuilderGenerator            _roomBuilderGenerator;

    typedef std::vector< RoomBuilder* > BuilderList;
    typedef std::vector< Room >         RoomList;

    bool IsRoomOkay( const Room& room, const RoomList& otherRooms );
    void DigCorridor( Map* map, const Room& first, const Room& second, bool vertical );

};

template< class RoomBuilder >
void MapBuilder::AddRoomBuilder( uint weight )
{
    _roomBuilderGenerator.AddType< RoomBuilder >( weight );
}

#endif
